﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace xna_game_engine.source
{
    abstract public class BaseCharacter
    {
        // Members
        protected Dictionary<string, SkillBase> mKnownSkills;   // List of known skills
        protected String mName, mClass;
        protected Texture2D mFrameImage, mModel;
        protected TongaTimer mHpRegenTick;
        protected Vector2 mPos;
        protected CTalentTree mTalentTree;
        protected Dictionary<string, int> mInventory;
        protected Rectangle mBoundingBox;

        //////////////////////
        // Stat related info
        protected int mStrength, mAgility, mFocus, mSpeed;      // Major stats
        protected int mAtk, mDef, mSta, mCrt;                   // Combat stats
        protected float mCurHp, mMaxHp, mCurPower, mMaxPower, mCurXP, mMaxXp; // Derived stats 
        
        //////////////////////
        // Level related info
        protected int mCurLevel, mXpWorth, mGold;
        protected Dictionary<int, int> mLevelTable;

        /////////////////////
        // Skill related info
        public enum FaceButtons { A_BUTTON, B_BUTTON, X_BUTTON, Y_BUTTON };

        // Functions
        #region
        public BaseCharacter()
        {
            // constructor
            mHpRegenTick = new TongaTimer(3.0f);
            mCurLevel = 1;
            mInventory = new Dictionary<string, int>();
        }

        public void AddItemToInventory(BaseItem item)
        {
            if (mInventory.ContainsKey(item.Name))
            {
                mInventory[item.Name] += 1;
            }
            else
            {
                mInventory.Add(item.Name, 1);
            }
        }

        /// <summary>
        /// Modify the character's health value
        /// </summary>
        /// <param name="amount">Amount to modify health, send negative to hurt</param>
        virtual public void ModHealth(float amount, Color textColor)
        {
            mCurHp += amount;
            mCurHp = MathHelper.Clamp(mCurHp, 0.0f, mMaxHp);
        }
        #endregion

        // Force some overrides
        abstract public void Update(GameTime gt);
        abstract public void LevelUp();
        abstract public void NormalAttack();
        abstract public void OnSkillUse(FaceButtons button);
        // End forced overrides

        virtual public void Draw()
        {
            GameSystems.Graphics.DrawImage(mModel, mPos, Color.Red);
        }

        virtual public void AddTalentPoint(int index_in_tree)
        {
            Console.WriteLine("Talent point added to character with no talent trees...gg.");
        }

        virtual public void AwardKill(Enemy victim)
        {
            mCurXP += victim.XpValue;
            //mGold += victim.Gold;
            GameGlobals.LootManager.AddLootPile(victim.Loot);
            if (mCurXP >= mMaxXp)
            {
                mCurXP = (mCurXP - mMaxXp);
                mMaxXp *= 1.10f;
                LevelUp();
            }
        }

        // Properties
        #region
        public float HealthPercent
        {
            get {return mCurHp / mMaxHp; }
            //set { mCurHp = mMaxHp * value; }
        }
        public float PowerPercent
        {
            get { return mCurPower / mMaxPower; }
            //set { mCurPower = mMaxPower * value; }
        }

        public float CurHealth
        {
            get { return mCurHp; }
            set { mCurHp = value; }
        }

        public float MaxHealth
        {
            get { return mMaxHp; }
            set { mMaxHp = value; }
        }

        public int CurPower
        {
            get { return (int)mCurPower; }
        }

        public int MaxPower
        {
            get { return (int)mMaxPower; }
        }

        public Texture2D UnitFrameImage
        {
            get { return mFrameImage; }
        }

        public int Level
        {
            get { return mCurLevel; }
        }

        public int Strength
        {
            get { return mStrength; }
        }
        public int Agility
        {
            get { return mAgility; }
        }
        public int Focus
        {
            get { return mFocus; }
        }

        public string Class
        {
            get { return mClass; }
        }

        public int Gold
        {
            get { return mGold; }
            set
            {
                if (value >= 0)
                {
                    mGold = value;
                }
            }
        }

        public Dictionary<string, int> Inventory
        {
            get { return mInventory; }
        }

        public Rectangle Bounds
        {
            get { return mBoundingBox; }
        }

        public string Name
        {
            get { return mName; }
        }

        public float ExpPercent
        {
            get {return mCurXP / mMaxXp; }
            //set { mCurHp = mMaxHp * value; }
        }

        public Vector2 Position
        {
            get { return mPos; }
        }
        // End Properties
#endregion

    }
}
